package client.view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.net.UnknownHostException;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;

import client.ClientMain;

public class ClientViewController extends Thread
{
	private ClientConnectWindow clientConnectWindow;
	private ClientLoginWindow clientLoginWindow;
	private ClientConsoleWindow clientConsoleView;
	private ClientCommunicationWindow clientCommunicationWindow;
	
	public ClientViewController()
	{
		this.clientConnectWindow = new ClientConnectWindow();
		this.clientLoginWindow = new ClientLoginWindow();
		this.clientConsoleView = new ClientConsoleWindow();
		this.clientCommunicationWindow = new ClientCommunicationWindow();
		
		this.clientConnectWindow.getButtonConnect().addActionListener(new ButtonConnectActionListener());
		this.clientLoginWindow.getButtonLogin().addActionListener(new ButtonLoginActionListener());
		this.clientCommunicationWindow.getButtonSend().addActionListener(new ButtonSendActionListener());
		
		this.clientConnectWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.clientLoginWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.clientCommunicationWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		this.clientCommunicationWindow.addWindowListener(new CommunicationWindowListener());
		
		cleanFields();
	}
	
	public void openConnectWindow()
	{
		this.clientConnectWindow.setVisible(true);
	}
	
	public void closeConnectWindow()
	{
		this.clientConnectWindow.setVisible(false);
	}
	
	public void openLoginWindow()
	{
		this.clientLoginWindow.setVisible(true);
	}
	
	public void closeLoginWindow()
	{
		this.clientLoginWindow.setVisible(false);
	}
	
	public void openChatWindow()
	{
		this.clientCommunicationWindow.setVisible(true);
	}
	
	private void cleanFields()
	{
		this.clientConnectWindow.getTextFieldHost().setText("");
		this.clientConnectWindow.getTextFieldPort().setText("");
		this.clientConnectWindow.getLblError().setText("");
		this.clientLoginWindow.getTextFieldUsername().setText("");
		this.clientLoginWindow.getLblError().setText("");
		this.clientCommunicationWindow.getTextAreaMessages().setText("");
		this.clientCommunicationWindow.getTextFieldMessage().setText("");
	}
	
	public String getHost()
	{
		return this.clientConnectWindow.getTextFieldHost().getText();
	}
	
	public int getPort()
	{
		return Integer.valueOf(this.clientConnectWindow.getTextFieldPort().getText());
	}
	
	public String getUsername()
	{
		return this.clientLoginWindow.getTextFieldUsername().getText();
	}
		
	class ButtonConnectActionListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent arg0)
		{
			try
			{
				ClientMain.openSocket(getHost(), getPort());
				closeConnectWindow();
				openLoginWindow();
			}
			catch (UnknownHostException e)
			{
				ClientViewController.this.clientConnectWindow.getLblError().setText(e.getMessage());
				ClientViewController.this.clientConsoleView.printLog(e);
			}
			catch (IOException e)
			{
				ClientViewController.this.clientConnectWindow.getLblError().setText(e.getMessage());
				ClientViewController.this.clientConsoleView.printLog(e);
			}
		}
	}
	
	class ButtonLoginActionListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent arg0)
		{
			ClientMain.sendUsernameMessage(getUsername());
		}
	}
	
	class ButtonSendActionListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent arg0)
		{
			final String to = (String) ClientViewController.this.clientCommunicationWindow.getListOnlineClients().getSelectedValue();
			final String message =  ClientViewController.this.clientCommunicationWindow.getTextFieldMessage().getText();
			ClientMain.sendTextMessage(message, to);
			ClientViewController.this.showMessage(ClientMain.getUsername(), message);
			ClientViewController.this.clientCommunicationWindow.getTextFieldMessage().setText("");
		}
	}
	
	class CommunicationWindowListener implements WindowListener
	{
		@Override
		public void windowActivated(WindowEvent e)
		{
		}

		@Override
		public void windowClosed(WindowEvent e)
		{
		}

		@Override
		public void windowDeactivated(WindowEvent e)
		{
		}

		@Override
		public void windowDeiconified(WindowEvent e)
		{
		}

		@Override
		public void windowIconified(WindowEvent e)
		{
		}

		@Override
		public void windowOpened(WindowEvent e)
		{
		}

		@Override
		public void windowClosing(WindowEvent e)
		{
			ClientMain.sendLogoutRequestMessage();
		}
	}

	public void printLog(final String string)
	{
		this.clientConsoleView.printLog(string);
	}
	
	public void printLog(final Exception exception)
	{
		this.clientConsoleView.printLog(exception);
	}

	public void printLoginError(final String string)
	{
		this.clientLoginWindow.getLblError().setText(string);
	}
	
	public void populateListOnlineClients(final String list)
	{
		final String listWithoutBracket = list.substring(1, list.length()-1);
		final String[] items = listWithoutBracket.split(", ");
		
		DefaultListModel listModel = new DefaultListModel();
		for (int i = 0; i < items.length; i++)   
		{
			listModel.addElement(items[i]); 
		}

		this.clientCommunicationWindow.getListOnlineClients().setModel(listModel);
	}

	public void showMessage(final String from, final String text)
	{
		final String message = from + " >>> " + text + "\n";
		this.clientCommunicationWindow.getTextAreaMessages().append(message);
	}
}
